﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using FlexCell;
using YArchitech.LIB;
using YArchitech.Revit;
using YJKGeometryFuncs;
using YJKRevitStructModel.Data;
using YJKRevitStructModel.Kit;

namespace YJKRevitStructModel.Forms
{
	public partial class DeductionForm : System.Windows.Forms.Form
	{
		public DeductionForm(UIDocument uiDoc, Dictionary<ElementDataPack, List<ElementDataPack>> dicDeductionWall, Dictionary<ElementDataPack, List<ElementDataPack>> dicDeductionColumn, Dictionary<ElementDataPack, List<ElementDataPack>> dicDisplayWall, Dictionary<ElementDataPack, List<ElementDataPack>> dicDisplayColumn)
		{
			this.InitializeComponent();
			this.m_dicDeductionColumn = dicDeductionColumn;
			this.m_dicDeductionWall = dicDeductionWall;
			this.m_dicDisplayColumn = dicDisplayColumn;
			this.m_dicDisplayWall = dicDisplayWall;
			foreach (KeyValuePair<ElementDataPack, List<ElementDataPack>> keyValuePair in this.m_dicDisplayColumn)
			{
				if (keyValuePair.Value == null)
				{
					this.m_ColumnNum++;
				}
				else
				{
					this.m_ColumnNum += keyValuePair.Value.Count;
				}
			}
			foreach (KeyValuePair<ElementDataPack, List<ElementDataPack>> keyValuePair2 in this.m_dicDisplayWall)
			{
				if (keyValuePair2.Value == null)
				{
					this.m_WallNum++;
				}
				else
				{
					this.m_WallNum += keyValuePair2.Value.Count;
				}
			}
			this.m_uiDoc = uiDoc;
			this.m_doc = this.m_uiDoc.Document;
			this.initGrid();
		}

		private void DeductionForm_Load(object sender, EventArgs e)
		{
			//base.Icon = Resource.YArchitechIcon;
			this.readFileData();
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		[DllImport("user32.dll")]
		public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

		public void PressEsc()
		{
			int bVk = 27;
			int dwFlags = 0;
			int dwFlags2 = 2;
			int wMsg = 7;
			DeductionForm.SendMessage(CmdStructuralModelDeduction._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			DeductionForm.keybd_event((byte)bVk, 0, dwFlags, 0);
			DeductionForm.keybd_event((byte)bVk, 0, dwFlags2, 0);
		}

		protected override bool ProcessKeyEventArgs(ref Message m)
		{
			int num = 256;
			int num2 = 27;
			if (m.Msg == num && m.WParam.ToInt32() == num2)
			{
				base.Close();
			}
			return base.ProcessKeyEventArgs(ref m);
		}

		private void btndeduction_Click(object sender, EventArgs e)
		{
			this.btndeduction.Enabled = false;
			this.ClearBoxCurves(true);
			RevitVersionFuncs.ClearSelection(this.m_uiDoc.Selection);
			if (DeductionKit.DeductionWallAndColumn(this.m_doc, this.m_dicDeductionWall, this.m_dicDeductionColumn))
			{
				this.m_dicDeductionColumn.Clear();
				this.m_dicDeductionWall.Clear();
			}
			this.btndeduction.Enabled = true;
		}

		private void initGrid()
		{
			this.grid1.Row(0).Visible = false;
			this.grid1.Column(0).Visible = false;
			this.grid1.Rows = 3 + this.m_WallNum + this.m_ColumnNum;
			this.grid1.Cols = 5;
			this.grid1.Column(1).Width = (short)((double)this.grid1.Width * 0.1);
			this.grid1.Column(2).Width = (short)((double)this.grid1.Width * 0.4);
			this.grid1.Column(3).Width = (short)((double)this.grid1.Width * 0.25);
			this.grid1.Column(4).Width = (short)((double)this.grid1.Width * 0.25);
			this.grid1.Range(1, 1, 1, 3).Merge();
			this.grid1.Locked = false;
			this.grid1.ShowResizeTip = true;
			this.grid1.Refresh();
			this.grid1.Cell(1, 1).Text = "建筑构件";
			this.grid1.Cell(1, 1).Alignment = AlignmentEnum.CenterTop;
			this.grid1.Cell(1, 4).Text = "结构构件";
			this.grid1.Cell(1, 4).Alignment = AlignmentEnum.CenterTop;
			this.grid1.Cell(2, 1).Text = "类型";
			this.grid1.Cell(2, 2).Text = "名称";
			this.grid1.Cell(2, 3).Text = "ID";
			this.grid1.Cell(2, 4).Text = "ID";
			int num = 3;
			this.InputDataToGrid(ref num, this.m_dicDisplayWall);
			this.InputDataToGrid(ref num, this.m_dicDisplayColumn);
			if (this.m_WallNum > 1)
			{
				this.grid1.Range(3, 1, this.m_WallNum + 2, 1).Merge();
			}
			if (this.m_ColumnNum > 1)
			{
				this.grid1.Range(this.m_WallNum + 3, 1, this.m_WallNum + this.m_ColumnNum + 3 - 1, 1).Merge();
			}
			if (this.m_WallNum > 0)
			{
				this.grid1.Cell(3, 1).Text = "墙体";
			}
			if (this.m_ColumnNum > 0)
			{
				this.grid1.Cell(this.m_WallNum + 3, 1).Text = "柱";
			}
			this.grid1.Locked = true;
		}

		private void InputDataToGrid(ref int idxCell, Dictionary<ElementDataPack, List<ElementDataPack>> dicDisplayElem)
		{
			foreach (KeyValuePair<ElementDataPack, List<ElementDataPack>> keyValuePair in dicDisplayElem)
			{
				ElementId selfElementId = keyValuePair.Key.SelfElementId;
				if (keyValuePair.Value == null)
				{
					this.grid1.Cell(idxCell, 2).Text = "";
					this.grid1.Cell(idxCell, 3).Text = "";
					this.grid1.Cell(idxCell, 4).Text = selfElementId.ToString();
					idxCell++;
				}
				else
				{
					foreach (ElementDataPack elementDataPack in keyValuePair.Value)
					{
						ElementId selfElementId2 = elementDataPack.SelfElementId;
						this.grid1.Cell(idxCell, 2).Text = elementDataPack.StrTypeName;
						this.grid1.Cell(idxCell, 3).Text = selfElementId2.ToString();
						this.grid1.Cell(idxCell, 4).Text = selfElementId.ToString();
						idxCell++;
					}
				}
			}
		}

		private void grid1_DoubleClick(object Sender, EventArgs e)
		{
			MouseEventArgs mouseEventArgs = e as MouseEventArgs;
			Cell cell = this.grid1.HitTest(mouseEventArgs.X, mouseEventArgs.Y);
			int col = cell.Col;
			int row = cell.Row;
			if (col < 2 || row < 3)
			{
				return;
			}
			int num = this.grid1.Cell(row, 4).Text.ToInt(0);
			CurveArray boxCurveAry = new CurveArray();
			List<ElementId> list = new List<ElementId>();
			if (((row < this.m_WallNum + 3) ? "墙体" : "柱") == "墙体")
			{
				using (Dictionary<ElementDataPack, List<ElementDataPack>>.Enumerator enumerator = this.m_dicDisplayWall.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						KeyValuePair<ElementDataPack, List<ElementDataPack>> keyValuePair = enumerator.Current;
						if (keyValuePair.Key.SelfElementId.IntegerValue == num)
						{
							boxCurveAry = keyValuePair.Key.ArCrvEdage;
							if (keyValuePair.Value == null)
							{
								break;
							}
							using (List<ElementDataPack>.Enumerator enumerator2 = keyValuePair.Value.GetEnumerator())
							{
								while (enumerator2.MoveNext())
								{
									ElementDataPack elementDataPack = enumerator2.Current;
									list.Add(elementDataPack.SelfElementId);
								}
								break;
							}
						}
					}
					goto IL_1BF;
				}
			}
			foreach (KeyValuePair<ElementDataPack, List<ElementDataPack>> keyValuePair2 in this.m_dicDisplayColumn)
			{
				if (keyValuePair2.Key.SelfElementId.IntegerValue == num)
				{
					boxCurveAry = keyValuePair2.Key.ArCrvEdage;
					if (keyValuePair2.Value == null)
					{
						break;
					}
					using (List<ElementDataPack>.Enumerator enumerator2 = keyValuePair2.Value.GetEnumerator())
					{
						while (enumerator2.MoveNext())
						{
							ElementDataPack elementDataPack2 = enumerator2.Current;
							list.Add(elementDataPack2.SelfElementId);
						}
						break;
					}
				}
			}
			IL_1BF:
			this.ZoomToElement(list, boxCurveAry);
		}

		private void ZoomToElement(List<ElementId> ids, CurveArray boxCurveAry)
		{
			if (ids.Count > 0)
			{
				this.m_uiDoc.ShowElements(ids);
				List<Element> list = new List<Element>();
				foreach (ElementId elementId in ids)
				{
					list.Add(this.m_uiDoc.Document.GetElement(elementId));
				}
				RevitVersionFuncs.SetSelection(this.m_uiDoc.Selection, list);
				this.m_uiDoc.RefreshActiveView();
			}
			if (boxCurveAry.Size > 0)
			{
				this.DrawBoxs(boxCurveAry);
			}
			else
			{
				this.ClearBoxCurves(true);
			}
			if (ids.Count == 0)
			{
				this.m_uiDoc.ShowElements(this.m_BoxCurvesId);
				List<Element> list2 = new List<Element>();
				foreach (ElementId elementId2 in this.m_BoxCurvesId)
				{
					list2.Add(this.m_doc.GetElement(elementId2));
				}
				RevitVersionFuncs.SetSelection(this.m_uiDoc.Selection, list2);
			}
		}

		private void ClearBoxCurves(bool includeTranssaction)
		{
			Transaction transaction = null;
			try
			{
				if (includeTranssaction)
				{
					transaction = new Transaction(this.m_doc);
					transaction.Start("delete box curves");
				}
				if (this.m_BoxCurvesId.Count > 0)
				{
					this.m_doc.Delete(this.m_BoxCurvesId);
					this.m_BoxCurvesId.Clear();
				}
				if (includeTranssaction)
				{
					transaction.Commit();
				}
			}
			catch (Exception)
			{
				if (includeTranssaction && transaction != null)
				{
					transaction.RollBack();
				}
				this.m_BoxCurvesId.Clear();
			}
		}

		private void DrawBoxs(CurveArray boxCurveAry)
		{
			double z = boxCurveAry.get_Item(0).GetEndPoint(0).Z;
			Autodesk.Revit.DB.View planViewByZ = this.GetPlanViewByZ(z);
			if (!planViewByZ.Equals(this.m_doc.ActiveView))
			{
				this.m_uiDoc.ActiveView = planViewByZ;
			}
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(this.m_doc);
				transaction.Start("draw box");
				if (this.m_BoxCurvesId.Count > 0)
				{
					this.m_doc.Delete(this.m_BoxCurvesId);
					this.m_BoxCurvesId.Clear();
				}
				this.ClearBoxCurves(false);
				DetailCurveArray detailCurveArray = this.m_doc.Create.NewDetailCurveArray(this.m_doc.ActiveView, boxCurveAry);
				if (this.GetLineStyle())
				{
					List<ElementId> list = new List<ElementId>();
					foreach (object obj in detailCurveArray)
					{
						DetailCurve detailCurve = (DetailCurve)obj;
						detailCurve.LineStyle = this.m_LineStyle;
						this.m_BoxCurvesId.Add(detailCurve.Id);
						list.Add(detailCurve.Id);
					}
					this.m_newLinePatternElem = LinePatternElement.GetLinePatternElementByName(this.m_doc, "虚线");
					this.m_doc.ActiveView.SetYJKProjLinePatternOverrideByElement(list, this.m_newLinePatternElem);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				if (transaction != null)
				{
					transaction.RollBack();
				}
			}
		}

		private bool GetLineStyle()
		{
			if (this.m_LineStyle != null)
			{
				return true;
			}
			Category category = this.m_doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (category == null)
			{
				return false;
			}
			int num = 6;
            Autodesk.Revit.DB.Color lineColor = new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0);
			if (!category.SubCategories.Contains(this.m_StrLineName))
			{
				if (!this.CreateLineStyle(num, this.m_StrLineName, lineColor, ref category))
				{
					return false;
				}
			}
			else
			{
				Category category2 = category.SubCategories.get_Item(this.m_StrLineName);
				category2.LineColor = lineColor;
				category2.SetLineWeight(num, (Autodesk.Revit.DB.GraphicsStyleType)1);
			}
			foreach (Element element in new FilteredElementCollector(this.m_doc).OfClass(typeof(GraphicsStyle)))
			{
				GraphicsStyle graphicsStyle = element as GraphicsStyle;
				if (graphicsStyle != null && graphicsStyle.Name.CompareTo(this.m_StrLineName) == 0)
				{
					this.m_LineStyle = graphicsStyle;
				}
			}
			return this.m_LineStyle != null;
		}

        private bool CreateLineStyle(int lineWidth, string typeName, Autodesk.Revit.DB.Color lineColor, ref Category lineCategory)
		{
			bool result;
			try
			{
				Category category = this.m_doc.Settings.Categories.NewSubcategory(lineCategory, typeName);
				category.LineColor = lineColor;
				category.SetLineWeight(lineWidth, (Autodesk.Revit.DB.GraphicsStyleType)1);
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
				ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(LinePatternElement));
				filteredElementCollector.WherePasses(elementClassFilter);
				foreach (Element element in filteredElementCollector)
				{
					this.m_newLinePatternElem = (element as LinePatternElement);
					if (this.m_newLinePatternElem.GetLinePattern().Name == "虚线")
					{
						break;
					}
				}
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private void btncancle_Click(object sender, EventArgs e)
		{
			this.ClearBoxCurves(true);
			this.WriteFileData();
			RevitVersionFuncs.ClearSelection(this.m_uiDoc.Selection);
			this.PressEsc();
		}

		private void DeductionForm_FormClosed(object sender, FormClosedEventArgs e)
		{
			this.ClearBoxCurves(true);
			this.WriteFileData();
			RevitVersionFuncs.ClearSelection(this.m_uiDoc.Selection);
			this.PressEsc();
		}

		private void readFileData()
		{
			string path = Product.UserDataLocation + "\\DeductionForm.dat";
			if (!File.Exists(path))
			{
				base.StartPosition = FormStartPosition.CenterScreen;
				return;
			}
			try
			{
				FileStream fileStream = new FileStream(path, FileMode.Open);
				StreamReader streamReader = new StreamReader(fileStream);
				streamReader.BaseStream.Seek(0L, SeekOrigin.Begin);
				base.StartPosition = FormStartPosition.Manual;
				int x = Convert.ToInt32(streamReader.ReadLine());
				int y = Convert.ToInt32(streamReader.ReadLine());
				base.Location = new System.Drawing.Point(x, y);
				streamReader.Close();
				fileStream.Close();
			}
			catch (Exception)
			{
				throw;
			}
		}

		private void WriteFileData()
		{
			FileStream fileStream = new FileStream(Product.UserDataLocation + "\\DeductionForm.dat", FileMode.Create);
			StreamWriter streamWriter = new StreamWriter(fileStream);
			int x = base.Location.X;
			int y = base.Location.Y;
			streamWriter.WriteLine(x.ToString());
			streamWriter.WriteLine(y.ToString());
			streamWriter.Flush();
			streamWriter.Close();
			fileStream.Close();
		}

		private Autodesk.Revit.DB.View GetPlanViewByZ(double ElevatorZ)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(ViewPlan));
			List<Element> list = filteredElementCollector.WherePasses(elementClassFilter).WhereElementIsNotElementType().ToElements() as List<Element>;
			list.RemoveAll((Element r) => (r as ViewPlan).IsTemplate);
			List<Element> list2 = (from r in list.Distinct(new ViewGenLevelDictinct()).ToList<Element>()
			orderby (r as ViewPlan).GenLevel.Elevation
			select r).ToList<Element>();
			int i = 0;
			while (i < list2.Count)
			{
				ViewPlan viewPlan = list2[i] as ViewPlan;
				if (viewPlan.GenLevel != null && (int)viewPlan.ViewType == 1 && Geometry.Lessthan_Or_Equal(ElevatorZ, viewPlan.GenLevel.Elevation))
				{
					if (i == 0)
					{
						return viewPlan;
					}
					return list2[i] as ViewPlan;
				}
				else
				{
					i++;
				}
			}
			return list2[list2.Count - 1] as ViewPlan;
		}

		private UIDocument m_uiDoc;

		private Document m_doc;

		private Dictionary<ElementDataPack, List<ElementDataPack>> m_dicDeductionWall;

		private Dictionary<ElementDataPack, List<ElementDataPack>> m_dicDeductionColumn;

		private Dictionary<ElementDataPack, List<ElementDataPack>> m_dicDisplayWall;

		private Dictionary<ElementDataPack, List<ElementDataPack>> m_dicDisplayColumn;

		private int m_WallNum;

		private int m_ColumnNum;

		private GraphicsStyle m_LineStyle;

		public string m_StrLineName = "HYPositionBoxDot";

		private LinePatternElement m_newLinePatternElem;

		private List<ElementId> m_BoxCurvesId = new List<ElementId>();

		public bool IfBreak = true;
	}
}
